﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Microsoft.Extensions.DependencyInjection;

using zijian666.WorkScheduler.Abstractions;

namespace zijian666.WorkScheduler;

public class WorkScheduler
{
    private readonly Dictionary<string, Lazy<IServiceScope>> _settings;
    private readonly IServiceProvider _services;
    public WorkScheduler(IServiceProvider services)
    {
        _services = services ?? throw new ArgumentNullException(nameof(services));
        _settings = new(StringComparer.OrdinalIgnoreCase);
        foreach (var name in services.GetServices<WorkSchedulerSettings>().Select(x => x.Name).Distinct())
        {
            if (name is not null)
            {
                _settings[name] = new(() => services.CreateScope());
            }
        }
    }

    public string? GetScopeName(IServiceProvider? provider)
    {
        if (provider is null)
        {
            return null;
        }
        foreach (var item in _settings)
        {
            if (item.Value.IsValueCreated)
            {
                if (provider.Equals(item.Value.Value.ServiceProvider))
                {
                    return item.Key;
                }
                else if (provider is IEquatable<IServiceProvider> x && x.Equals(item.Value.Value.ServiceProvider))
                {
                    return item.Key;
                }
            }
        }
        return null;
    }

    public string? GetScopeName(IServiceScope? scope)
        => GetScopeName(scope?.ServiceProvider);

    public IWorkService? GetWorkService(string name)
    {
        if (name is null)
        {
            return null;
        }
        if (_settings.TryGetValue(name, out var settings))
        {
            return settings.Value.ServiceProvider.GetService<IWorkService>();
        }
        return null;
    }

}
